package com.cnswhy.cloud.server.comsumer.consumer.split;

import com.cnswhy.cloud.common.core.entity.constant.CnswhyConstant;
import com.cnswhy.cloud.common.core.mybatis.conditions.Wraps;
import com.cnswhy.cloud.common.core.utils.SystemClockUtil;
import com.cnswhy.cloud.common.redis.annotation.RedisLock;
import com.cnswhy.cloud.common.redis.model.LockTimeoutStrategy;
import com.cnswhy.cloud.common.redis.service.RedisService;
import com.cnswhy.cloud.server.common.entity.enumeration.OrderReportType;
import com.cnswhy.cloud.server.common.entity.mq.OrderReportMQ;
import com.cnswhy.cloud.server.comsumer.event.OrderReportEvent;
import com.cnswhy.cloud.server.core.entity.OrderReport;
import com.cnswhy.cloud.server.core.service.OrderReportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class OrderReportConsumer implements OrderReportEvent {
    @Autowired
    RedisService redisService;
    @Autowired
    OrderReportService orderReportService;
    @Override
    public void report(OrderReportMQ orderReportMQ) {
        String settDate = SystemClockUtil.getSettDateyyyyMMdd();
        if(orderReportMQ.getOrderReportType() == null){
            return;
        }
        if(existReportOrderId(orderReportMQ.getOrderId(),orderReportMQ.isSuccess())){
            return;
        }
        OrderReport orderReport = getOrderReport(settDate,orderReportMQ.getOrderReportType());
        updateOrderReport(orderReport.getId(), orderReportMQ.getTransAmt(), orderReportMQ.isSuccess());
        return;
    }
    @RedisLock(name = "existReportOrderId", waitTime = 10,leaseTime = 60,keys = {"#reportOrderId"},lockTimeoutStrategy = LockTimeoutStrategy.FAIL_FAST)
    private boolean existReportOrderId(String reportOrderId,boolean success){
        String abc = (String)redisService.hget("report.order." , reportOrderId);
        if (StringUtils.isNotBlank(abc) && abc.equals(Boolean.valueOf(success).toString())) {
            return true;
        }
        redisService.hset("report.order." , reportOrderId, Boolean.valueOf(success).toString(), CnswhyConstant.DAY_SECONDS / 24);
        return false;
    }
    @RedisLock(name = "updateOrderReport", waitTime = 10,leaseTime = 60,keys = {"#id"},lockTimeoutStrategy = LockTimeoutStrategy.FAIL_FAST)
    private OrderReport updateOrderReport(Long id,Long transAmt, boolean success){
        OrderReport orderReport = orderReportService.getById(id);
        if(success){
            orderReport.setSuccessCount(orderReport.getSuccessCount() + 1);
            orderReport.setTransAmt(orderReport.getTransAmt() + transAmt);
        }else{
            orderReport.setTransCount(orderReport.getTransCount() + 1);
        }
        orderReport.setSuccessRate( orderReport.getSuccessCount() * 10000 / orderReport.getTransCount());
        orderReportService.updateById(orderReport);
        return orderReport;

    }
    @RedisLock(name = "getOrderReport", waitTime = 10,leaseTime = 60,keys = {"#settDate","#orderReportType"},lockTimeoutStrategy = LockTimeoutStrategy.FAIL_FAST)
    private OrderReport getOrderReport(String settDate, OrderReportType orderReportType){
        OrderReport orderReport = orderReportService.getOne(
                Wraps.<OrderReport>lbQ().eq(OrderReport::getOrderReportType, orderReportType)
                .eq(OrderReport::getSettDate,settDate)
        );
        if(orderReport == null){
            orderReport = new OrderReport();
            orderReport.setSettDate(settDate);
            orderReport.setOrderReportType(orderReportType);
            orderReport.setTransCount(0L);
            orderReport.setSuccessCount(0L);
            orderReport.setSuccessRate(0L);
            orderReport.setTransAmt(0L);
            orderReportService.save(orderReport);
        }
        return orderReport;
    }
}
